package com.nakamachizu.controller;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.mobylet.core.Carrier;
import org.mobylet.core.Mobylet;
import org.mobylet.core.MobyletFactory;
import org.mobylet.core.device.DeviceDisplay;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.controller.validator.Validators;
import org.slim3.util.StringUtil;

import com.google.appengine.api.datastore.GeoPt;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.nakamachizu.collection.ApiKeyMap;
import com.nakamachizu.constant.AppConstant;
import com.nakamachizu.model.MapData;
import com.nakamachizu.service.MapDataService;
import com.nakamachizu.service.StaticMapService;

public class StaticmapController extends Controller {

    private String keyStr;
    private String zoomLevel;
    private String centerLatStr;
    private String centerLngStr;
    private String add;
    
    @Override
    public Navigation run() {
        
        init();
        
        if(StringUtil.isEmpty(keyStr)){
           StaticMapService.printErrorGif(response, request);
           return null;
        }
        
        MapDataService mds = new MapDataService();
        MapData map = mds.getMapDataAccessKey(keyStr);
        if(map == null){
            StaticMapService.printErrorGif(response, request);
            return null;
        }
        
        Integer w = 600;
        Integer h = 370;
        
        Mobylet mobylet = MobyletFactory.getInstance();
        Carrier carrier = mobylet.getCarrier();
        if(!carrier.equals(Carrier.OTHER)){
            DeviceDisplay display = mobylet.getDisplay();
            w = display.getWidth();  //ブラウザ幅
            h = display.getHeight(); //ブラウザ高さ

            if(w == null || w.intValue() <= 0){
                w = 100;
            }
            if(h == null || h.intValue() <= 0){
                h = 100;
            }
            
            h = (int)(h * 0.7);

        }
        
        try{
            List<GeoPt> additional = null;
            if(!StringUtil.isEmpty(add)){
                String[] latlng = add.split(",");
                if(latlng != null && latlng.length == 2){
                    additional = new ArrayList<GeoPt>();
                    additional.add(new GeoPt(Float.parseFloat(latlng[0]), Float.parseFloat(latlng[1])));
                }
            }
            
            String apiKey = ApiKeyMap.API_KEY_MAP.get(request.getServerName());
            URL url = StaticMapService.getUrl(apiKey, map.getKey(), Double.parseDouble(centerLatStr), Double.parseDouble(centerLngStr), Integer.parseInt(zoomLevel), w, h, additional);
            if(url != null){
                if(url.getPath().length() > AppConstant.STATIC_MAP_URL_MAX_LENGTH()){
                    boolean big = true;
                    if(w < 300){
                        big = false;
                    }
                    StaticMapService.printOverFlowErrorGif(response, request, big);
                    return null;
                }else{
                    HTTPResponse res = URLFetchServiceFactory.getURLFetchService().fetch(url);
                    if(res.getResponseCode() == 200){
                        StaticMapService.printGif(response, res.getContent());
                        return null;
                    }
                }
            }

        }catch(IOException e){
            e.printStackTrace();
            StaticMapService.printErrorGif(response, request);
        }
        
        return null;
    }
    
    private void init(){
        keyStr = requestScope("key");
        zoomLevel = requestScope("zoom");
        centerLatStr = requestScope("cLat");
        centerLngStr = requestScope("cLng");
        if(StringUtil.isEmpty(zoomLevel)){
            zoomLevel = AppConstant.DEFAULT_ZOOM_LEVEL();
        }
        add = requestScope("add");
    }
    
    protected boolean validate() {
        boolean result = false;
        Validators v = new Validators(request);
        v.add("key", v.required());
        v.add("zoom", v.longRange(0, 19));
        v.add("cLat", v.floatType());
        v.add("cLng", v.floatType());
        
        result = v.validate();
        
        return result;
    }
}
